home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample PMSAM / PMSAM Framework / RoboSamSlot / Application.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  17.0 KB  |  775 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Application.cp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Tim Harnett
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <28>     2/27/95    TMH        adapt to use ETO16 universal headers
  13.         <27>     2/15/95    TMH        moved gEnableIOTrace here, use of GetSlot(slotCID)
  14.         <26>     2/14/95    CL        CAttribute & CRecord I/F changes
  15.         <25>     2/14/95    TMH        change gEnabledEWorldSlot to gHFSSlotEnabled
  16.         <24>     2/14/95    TMH        added use of TSlotThread::IsLetterInTheEventQueue
  17.         <23>     2/10/95    TMH        change so modify events are posted while the slot is busy
  18.         <22>      2/9/95    TMH        added LimitErrorReport flag
  19.         <21>      2/8/95    TMH        fixed so we finnish sending on quit and shutdown events
  20.         <19>      2/6/95    TMH        adapt to CEventQueue modifications
  21.         <18>    12/20/94    TMH        implement location eppc, removed some debugger breaks
  22.         <17>    12/16/94    TMH        removed ReSignal() in ::Run()
  23.         <16>    12/15/94    TMH        added gAssertsEnabled
  24.         <15>    12/13/94    TMH        avoid duplicate postings of some events
  25.         <14>    12/12/94    TMH        use of thread events
  26.         <13>     11/2/94    TMH        added initalize gEnableIOTrace from resource
  27.         <12>    10/20/94    TMH        validate system configuration
  28.         <11>    10/20/94    TMH        handle 'cnct' apple event
  29.         <10>    10/18/94    TMH        when a slot is created we put a entry into the setup record for
  30.                                     the directory
  31.          <9>    10/14/94    TMH        fixed AppleEvent dispatching to work correctly
  32.          <8>    10/11/94    TMH        CommThread integration
  33.          <7>     10/7/94    TMH        fix so no crash  if fail during IApplication
  34.          <6>     10/6/94    JHB        Added support for Gestalt checking
  35.          <5>     10/6/94    TMH        better error handling during initialization
  36.          <4>     10/4/94    TMH        added debug flag BreakEveryScheduleEPPC
  37.          <3>     10/3/94    TMH        added debug flag resource read
  38.          <2>     9/30/94    TMH        move incoming stuff to SlotThread
  39.          <2>     9/30/94    TMH        moved incoming stuff to slot thread
  40.          <1>     9/21/94    TMH        Use new Debug.cp ASSERT stuff,oops don't know how it got
  41.                                     orphaned.
  42.          <2>     9/21/94    TMH        move thread stuff to TThread.cp,.h and SlotThread.cp,.h
  43.          <1>     9/20/94    TMH        Abandon RoadsideRest embrace Mercury
  44.          <4>     9/20/94    TMH        some experimental but working threaded stuff
  45.          <3>      9/9/94    TMH        catch more failures, TIncoming/TOutgoing adaptations
  46.          <2>     6/17/94    TMH        experimental thread stuff
  47.                  3/29/94    TMH        xxx put comment here xxx
  48.  
  49.     To Do:
  50. */
  51.  
  52. #ifndef __RESOURCES__
  53. #include "Resources.h"
  54. #endif
  55.  
  56. #ifndef __APPLEEVENTS__
  57. #include "AppleEvents.h"
  58. #endif
  59.  
  60. #ifndef __AEREGISTRY__
  61. #include "AERegistry.h"
  62. #endif
  63.  
  64.  
  65. #ifndef __SOUND__
  66. #include <sound.h>
  67. #endif
  68.  
  69.  
  70. #ifndef __OCEERRORS__
  71. #include "OCEErrors.h"
  72. #endif
  73.  
  74. #ifndef __Debug__
  75. #include "Debug.h"
  76. #endif
  77.  
  78. #ifndef __PMSAMResources__
  79. #include "PMSAMResources.h"
  80. #endif
  81.  
  82. #ifndef __PMSAMResourceIDs__
  83. #include "PMSAMResourceIDs.h"
  84. #endif
  85.  
  86. #ifndef __CRecordID__
  87. #include "CRecordID.h"
  88. #endif
  89.  
  90. #ifndef __CAttribute__
  91. #include "CAttribute.h"
  92. #endif
  93.  
  94. #ifndef __Application__
  95. #include "Application.h"
  96. #endif
  97.  
  98. #ifndef __Thread__
  99. #include "TThread.h"
  100. #endif
  101.  
  102. #ifndef __SlotThread__
  103. #include "SlotThread.h"
  104. #endif
  105.  
  106. #ifndef __MSAMSlot__
  107. #include "MSAMSlot.h"
  108. #endif
  109.  
  110. #ifndef __ExternalSlot__
  111. #include "ExternalSlot.h"
  112. #endif
  113.  
  114. #ifndef __HalfGateway__
  115. #include "HalfGateway.h"
  116. #endif
  117.  
  118. #ifndef __ALetter__
  119. #include "ALetter.h"
  120. #endif
  121.  
  122. #ifndef __XLetter__
  123. #include "XLetter.h"
  124. #endif
  125.  
  126. #ifndef __Globals__
  127. #include "Globals.h"
  128. #endif
  129.  
  130.  
  131. #ifndef __UFAILURE__
  132. #include "UFailure.h"
  133. #endif
  134.  
  135. #ifndef __LogErrors__
  136. #include "LogErrors.h"
  137. #endif
  138.  
  139. #ifndef __CheckGestalt__
  140. #include "CheckGestalt.h"
  141. #endif
  142.     
  143.  
  144. //--------------------------------------
  145. //        m a i n 
  146. //--------------------------------------
  147.  
  148. //•••••••••
  149.  
  150.     TApplicationThread* gApplicationThread = 0;
  151.  
  152.     CSystemConfiguration* gSystemConfiguration = 0;
  153.  
  154.         //    debug flags
  155.     Boolean    gBreakEveryScheduleEPPC = false;
  156.     Boolean    gRunIfKeychainLocked = true;
  157.     Boolean    gDiagnosticsEnabled = false;
  158.     Boolean gHFSSlotEnabled = false;
  159.     Boolean    gEnableIOTrace = true;
  160.     
  161. //-------------------------------------------------------------------------------------------------
  162. void PlaySound( short resID );        // the compiler insists
  163. void PlaySound( short resID )
  164. {
  165.     Handle aHandle = GetResource('snd ', resID);
  166.     if ( aHandle != NULL ) {
  167.         HLock(aHandle);
  168.         OSErr result = SndPlay( NULL, (SndListHandle)aHandle, false );
  169.         HUnlock(aHandle);
  170.         ReleaseResource(aHandle);
  171.     } else {
  172.         SysBeep(20);
  173.     }
  174. }
  175.  
  176.  
  177. //•••••••••••••••••
  178.  
  179. //----------------------------------------------------------------
  180. void    ValidateSystem();        // the compiler insists
  181. void    ValidateSystem()
  182. {
  183.     ASSERT(gSystemConfiguration);
  184.  
  185.     //    We don't check for 7.1 or for PowerTalk.  We assume 
  186.     //    because we ARE running that our system has these.
  187.     
  188.     if( !gSystemConfiguration->HasCommToolbox() )
  189.         FailOSErr(errCommToolBoxNotInstalled);
  190.         
  191.     if( !gSystemConfiguration->HasThreadManager() )
  192.         FailOSErr(errThreadMgrNotInstalled);
  193.  
  194.     
  195.     if( !gSystemConfiguration->HasAppleEvents() )
  196.         FailOSErr(errNeedAppleEventSupport);
  197.  
  198.  
  199. }
  200.  
  201.  
  202.  
  203.  
  204. //-------------------------------------------------------------------------------------
  205. void main(void)
  206. {
  207.     
  208.     //    Initialize the Toolbox
  209.     
  210.     
  211.     Ptr                aMaxStackPtr;
  212.     
  213.     aMaxStackPtr = GetApplLimit();
  214.     aMaxStackPtr -= 0x4000;
  215.     SetApplLimit(aMaxStackPtr);
  216.     MaxApplZone();
  217.     MoreMasters();
  218.     MoreMasters();
  219. //    InitGraf(&qd.thePort);
  220.  
  221. ASSERT(0);
  222.  
  223.  
  224.     //    Read in the debug flags
  225.     
  226.     
  227.     extern Boolean gHFSSlotEnabled;
  228.     extern Boolean gBreakEveryScheduleEPPC;
  229.     extern Boolean gRunIfKeychainLocked;
  230.     extern Boolean gEnableIOTrace;
  231.     extern Boolean gAssertsEnabled;
  232.     extern Boolean gRecieveAfterSendNow;
  233.     extern Boolean gLimitErrorReports;
  234.     extern Boolean gDiagnosticsEnabled;
  235.     Handle rsrc = ::Get1Resource('Dflg',0);
  236.     if( rsrc != 0 ) {
  237.         gHFSSlotEnabled = ( ((**(char**)rsrc) & bHFSSlotEnable) != 0);
  238.         gBreakEveryScheduleEPPC = ( ((**(char**)rsrc) & bBreakOnScheduleEPPC) != 0);
  239.         gRunIfKeychainLocked = ( ((**(char**)rsrc) & bRunIfKeychainLocked) != 0);
  240.         gEnableIOTrace = ( ((**(char**)rsrc) & bEnableCommCaptureFile) != 0);
  241.         gAssertsEnabled = ( ((**(char**)rsrc) & bEnableAsserts) != 0);
  242.         gRecieveAfterSendNow = ( ((**(char**)rsrc) & bRecieveAfterSendNow) != 0);
  243.         gLimitErrorReports = ( ((**(char**)rsrc) & bLimitErrorReports) != 0);
  244.         gDiagnosticsEnabled = ( ((**(char**)rsrc) & bDiagnosticsEnabled) != 0);
  245.     }
  246.  
  247.  
  248.     gApplication = new TApplication;
  249.  
  250.     FailInfo fi;
  251.     Try(fi) {
  252.     
  253.         gSystemConfiguration = new CSystemConfiguration;
  254.         ValidateSystem();
  255.  
  256.         gApplication->IApplication();
  257.         gApplication->Run();
  258.         fi.Success();
  259.     } else {
  260.     
  261.         //    The place is comin' apart! We are outa  here!
  262.         LogError(fi.error);
  263.             
  264.     }
  265.     
  266.  
  267.  
  268.  
  269. }
  270.  
  271. //--------------------------------------
  272. //        T A p p l i c a t i o n
  273. //--------------------------------------
  274.  
  275. //-------------------------------------------------------------------------------------
  276. TApplication::TApplication()
  277. {
  278.     fAOCEHalfGateway = 0;
  279.     
  280.     fSetupRecordCID.source = fSetupRecordCID. seq = 0;    
  281.     fOCELocation = 0;
  282.     
  283.     fWNESleepTime = kSleepTime;
  284. }
  285.  
  286.  
  287. //-------------------------------------------------------------------------------------
  288. void TApplication::IApplication()
  289. {
  290.  
  291.     //    All the errors here are considered fatal.  Expect the application to
  292.     //    not start.
  293.  
  294.     this->InitializeAppleEvents();    
  295.     
  296.     gApplicationThread = new TApplicationThread;
  297.     gApplicationThread->IApplicationThread();
  298.  
  299.         
  300.     fAOCEHalfGateway = new TAOCEHalfGateway;
  301.     
  302.     this->InitAuth();
  303.  
  304.         // Get  AOCE keychain catalog
  305.     
  306.     DirParamBlock dirPB;
  307.     memset(&dirPB,0,sizeof(DirParamBlock));
  308.     DirGetOCESetupRefNum(&dirPB,false);        // Note that this cannot fail.  Ever.
  309.  
  310.     gKeyChainDSRefnum = dirPB.dirGetOCESetupRefNumPB.dsRefNum;
  311.     
  312.     
  313.         //    I'm At ... Location
  314.  
  315.  
  316.     fSetupRecordCID = dirPB.dirGetOCESetupRefNumPB.oceSetupRecordCID;
  317.     CRecordID    setupRID(gKeyChainDSRefnum ,fSetupRecordCID);
  318.     CAttribute    locationAttr(kLocationAttrTypeNum);
  319.     OSErr osErr = locationAttr.Read1Value(setupRID,&fOCELocation,sizeof(OCESetupLocation), gIdentity);
  320.     ASSERTNOERR(osErr);
  321.     FailOSErr(osErr);
  322.     
  323.  
  324.         // MSAM Record
  325.  
  326.  
  327.     MSAMParam    mailPB;
  328.     memset(&mailPB,0,sizeof(MSAMParam));
  329.     osErr = PMSAMGetMSAMRecord(&mailPB);
  330.     ASSERTNOERR(osErr);
  331.     if (osErr!=noErr)
  332.         FailOSErr(errMSAMSetupInfoCorrupt);
  333.  
  334.  
  335.         //    Read the configuration info for the slots.
  336.         
  337.         
  338.     fAOCEHalfGateway->SetupSlots(mailPB.pmsamGetMSAMRecord.msamCID);
  339.  
  340.  
  341.  
  342. }
  343.  
  344.  
  345.  
  346.  
  347. //-------------------------------------------------------------------------------------
  348. OSErr TApplication::InitAuth(void)
  349. {
  350.     AuthParamBlock authBlock;
  351.         
  352.     OSErr osErr = AuthGetLocalIdentity(&authBlock,false);
  353.     ASSERTNOERR(osErr);
  354.     if( osErr != 0 && !gRunIfKeychainLocked) {
  355.         PlaySound(2000);
  356.         FailOSErr(errAlreadyLogged);        // Pointless to log this. The mail box is not open!
  357.     }
  358.     
  359.     gIdentity = authBlock.getLocalIdentityPB.theLocalIdentity;
  360.     
  361.     
  362.     return osErr;
  363. }
  364.  
  365.  
  366.  
  367.  
  368.  
  369. //-------------------------------------------------------------------------------------
  370. void TApplication::Run()
  371. {
  372.     EventRecord theEvent;
  373.     Boolean gotEvt;
  374.     long        astackspace;
  375.     
  376.     FailInfo fi;
  377.     while (!gDone) {
  378.     
  379.         Try(fi) {
  380.         
  381.         
  382.             gotEvt = false;
  383.             gotEvt = WaitNextEvent(highLevelEventMask,&theEvent,fWNESleepTime,nil);
  384.             
  385.             gCurrentThread->Yield();
  386.             
  387.             if (gotEvt) {
  388.             
  389.                 this->HandleEvent(&theEvent);
  390.                     
  391.             } else {
  392.             
  393.                 // Time to see if we got any letters put in our inBin
  394.                 astackspace= StackSpace();
  395.                 ASSERTPRINT(astackspace>1024, ("Stack is low!\n"));
  396.                 
  397.             }
  398.  
  399.  
  400.             fi.Success();
  401.  
  402.  
  403.         } else {
  404.         
  405.             gDone = true;
  406.             LogError(fi.error);
  407.             
  408.         }
  409.     
  410.     
  411.     }
  412.     
  413.     
  414. }
  415.  
  416.  
  417.  
  418. //-------------------------------------------------------------------------------------
  419. void TApplication::HandleEvent(EventRecord *theEvent)
  420. {
  421.     
  422.     switch (theEvent->what) {
  423.         case kHighLevelEvent:
  424.             this->HandleHighLevelEvent(theEvent);
  425.             break;
  426.     }
  427.     
  428. }
  429.  
  430.  
  431.  
  432. //-------------------------------------------------------------------------------------
  433. void TApplication::HandleHighLevelEvent(EventRecord *theEvent)
  434. {
  435.  
  436.     if( theEvent->message == kMailAppleMailCreator ) {
  437.     
  438.  
  439.             //    We accept only     MailEPPCMsg
  440.  
  441.  
  442.         TargetID sender;
  443.         unsigned long refCon;
  444.         unsigned long msgLen = 0;
  445.         MailEPPCMsg mailEPPC;
  446.         MailEPPCMsg*    msgPtr = 0;
  447.         OSErr err = AcceptHighLevelEvent(&sender,&refCon,(Ptr)&mailEPPC,&msgLen);
  448.         if (err == bufferIsSmall ) {
  449.             if( msgLen == sizeof(MailEPPCMsg) )
  450.                 msgPtr = &mailEPPC;
  451.                 err = AcceptHighLevelEvent(&sender,&refCon,(Ptr)msgPtr,&msgLen);
  452.         }
  453.         ASSERTNOERR(err);
  454.  
  455.         if( err == 0 ) {
  456.             OSType messageID = * (unsigned long *) &theEvent->where;
  457.             short slotID = (short)theEvent->modifiers;
  458.     
  459.             if( msgPtr != 0 && mailEPPC.version != kMailEPPCMsgVersion)
  460.                 FailOSErr(kOCEVersionErr);
  461.                 
  462.                 
  463.             this->DoGatewayEvent(slotID, messageID, msgPtr);
  464.         }
  465.  
  466.  
  467.     } else {
  468.     
  469.         OSErr theErr = AEProcessAppleEvent(theEvent);
  470.         //if (theErr != errAEEventNotHandled)            // If the event is one we don't handle, do nothing
  471.         //    FailOSErr(theErr);
  472.         
  473.     }
  474.  
  475.  
  476. }
  477.  
  478.  
  479.  
  480. //-------------------------------------------------------------------------------------
  481. void TApplication::DoGatewayEvent(short slotID, long messageID,MailEPPCMsg* theEppc)
  482. {
  483.  
  484.     TSlotThread* slotThread = 0;
  485.     TMSAMSlot*    msamSlot;
  486.  
  487.  
  488.     long    threadEventID = 0;
  489.     long    threadEventData0 = 0;
  490.     Boolean    allowDuplicateThreadEvent = kAllowDuplicateEvent;
  491.  
  492.  
  493.     SMCA* smca = 0;
  494.     if(theEppc != 0 )
  495.         smca = theEppc->u.theSMCA;
  496.  
  497.  
  498.  
  499.     switch (messageID) {
  500.  
  501.         case kMailEPPCCreateSlot:
  502.             
  503.             ASSERT(smca);
  504.             
  505.             
  506.                     //    Create the slot id attribute.
  507.             
  508.             {
  509.             CRecordID   slotRecord(gKeyChainDSRefnum,smca->u.slotCID);
  510.             CAttribute slotIDAttr(kSlotIDAttrTypeNum);
  511.             short newSlotID = 1;        // hard code we handle only one for now.
  512.             OSErr osErr = slotIDAttr.Write1Value(slotRecord,&newSlotID,sizeof(short), gIdentity);
  513.             ASSERTNOERR(osErr);            
  514.  
  515.             msamSlot = fAOCEHalfGateway->GetSlot(smca->u.slotCID);
  516.             ASSERT(msamSlot);
  517.             msamSlot->SetSlotID(newSlotID);
  518.             
  519.             gDone = true;    // restart the PMSAM it works better that way!
  520.  
  521.             smca->result = noErr;
  522.             }
  523.             break;
  524.  
  525.  
  526.         case kMailEPPCContinue:
  527.         case kMailEPPCSchedule:
  528.         
  529.             //    ... Only if we are not busy.
  530.                 
  531.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  532.             if( (msamSlot != 0) && msamSlot->IsEnabled() && !msamSlot->Busy() )
  533.                 threadEventID = messageID;
  534.  
  535.             break;
  536.             
  537.  
  538.  
  539.         case kMailEPPCModifySlot:
  540.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  541.             if( msamSlot != 0)  {
  542.                 allowDuplicateThreadEvent = kDontAllowDuplicateEvent;
  543.                 threadEventID = messageID;
  544.             }
  545.             
  546.             smca->result = noErr;
  547.             break;
  548.             
  549.         case kMailEPPCMsgPending:
  550.         
  551.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  552.             if( (msamSlot != 0) && msamSlot->IsEnabled() && !msamSlot->Busy() ) {
  553.                 allowDuplicateThreadEvent = kDontAllowDuplicateEvent;
  554.                 threadEventID = messageID;
  555.             }
  556.                 
  557.             smca->result = noErr;
  558.             
  559.             break;
  560.  
  561.  
  562.         case kMailEPPCSendImmediate:
  563.         
  564.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  565.             
  566.             if( msamSlot != 0 &&  msamSlot->IsEnabled() ) {
  567.             
  568.                 slotThread = msamSlot->GetSlotThread();
  569.                 ASSERT(slotThread);
  570.                 
  571.                 long letterSeqNo = smca->userBytes;
  572.                 if( !slotThread->IsLetterInTheEventQueue(letterSeqNo) ) {    //    Not the same letter twice.
  573.                     threadEventID = kMailEPPCSendImmediate;
  574.                     threadEventData0 = letterSeqNo;
  575.                 }
  576.  
  577.  
  578.             }
  579.  
  580.             smca->result = noErr;
  581.             
  582.             break;
  583.  
  584.         case kMailEPPCLocationChanged:
  585.         
  586.             fOCELocation  = theEppc->u.locationInfo.location;
  587.             
  588.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  589.             ASSERT(msamSlot!=0);
  590.             if( msamSlot != 0 ) {
  591.                 msamSlot->SetLocationFlags(theEppc->u.locationInfo.active);
  592.                 allowDuplicateThreadEvent = kDontAllowDuplicateEvent;
  593.                 threadEventID = kMailEPPCModifySlot;
  594.             }
  595.             break;
  596.  
  597.  
  598.         case kMailEPPCDeleteSlot:
  599.             ASSERT(smca);
  600.             DebugStr("\p Received kMailEPPCDeleteSlot;g");
  601.             smca->result = noErr;
  602.             break;
  603.  
  604.         case kMailEPPCShutDown:
  605.             
  606.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  607.             slotThread = msamSlot->GetSlotThread();
  608.             ASSERT(slotThread);
  609.  
  610.             slotThread->FlushEvents('all ');        // remove pending events
  611.             slotThread->SetUserInterrupt('disc');
  612.             
  613.             while( msamSlot != 0 && msamSlot->Busy() )        // if busy finish sending
  614.                 gCurrentThread->Yield();
  615.  
  616.             gDone = true;
  617.                 
  618.             break;
  619.  
  620.         case kMailEPPCWakeup:
  621.             DebugStr("\p Received kMailEPPCWakeup;g");
  622.             break;
  623.  
  624.  
  625.             //    Don't care about these.
  626.             
  627.             
  628.         case kMailEPPCInQUpdate:
  629.         case kMailEPPCMsgOpened:
  630.         case kMailEPPCMailboxOpened:
  631.         case kMailEPPCMailboxClosed:
  632.             break;
  633.             
  634.         case kMailEPPCDeleteOutQMsg:
  635.     
  636.                 
  637.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  638.             if( msamSlot != 0 ) {
  639.             
  640.                 slotThread = msamSlot->GetSlotThread();
  641.                 ASSERT(slotThread);
  642.  
  643.                 slotThread->IsLetterInTheEventQueue(smca->userBytes,true);
  644.             }
  645.  
  646.             //••• still need to check if the message is the one currently being sent.
  647.             break;
  648.  
  649.  
  650.         case 'disc':            // disconnect -- only via AppleScript
  651.             
  652.             msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  653.             if( msamSlot != 0 && msamSlot->Busy() ) {        // don't bother if we are not already disconnected
  654.             
  655.                 slotThread = msamSlot->GetSlotThread();
  656.                 ASSERT(slotThread);
  657.  
  658.                 slotThread->FlushEvents(kMailEPPCSendImmediate);        // remove pending "send now's"
  659.                 
  660.                 slotThread->SetUserInterrupt('disc');
  661.                 
  662.             }
  663.  
  664.             break;
  665.             
  666.         default:
  667.             ASSERTPRINT(false,("Unrecognized MSAM EPPC message\n"));
  668.             break;
  669.     };
  670.  
  671.  
  672.  
  673.     if( threadEventID != 0 ) {
  674.     
  675.         msamSlot = fAOCEHalfGateway->GetSlot(slotID);
  676.         ASSERT(msamSlot!=0);
  677.         if( msamSlot != 0 ) {
  678.                                 
  679.             slotThread = msamSlot->GetSlotThread();
  680.             ASSERT(slotThread);
  681.             if( slotThread != 0) 
  682.                 slotThread->PostEvent(threadEventID,threadEventData0,allowDuplicateThreadEvent);
  683.                 
  684.         }
  685.         
  686.     }
  687.     
  688.     
  689.             
  690. }
  691.  
  692.  
  693. //--------------------------------------------------------------------------------------------------------
  694. void TApplication::InitializeAppleEvents()
  695. {
  696.  
  697.     // Look for all AppleEvent dispatch tables… 
  698.     short numberOfTables = Count1Resources('aedt');// Count the number of 'aedt' resources 
  699.     FailResError();
  700.  
  701.     Handle tableHandle = NULL;
  702.     
  703.     FailInfo fi;
  704.     Try(fi)
  705.     {
  706.         for (short tableIndex = 1; tableIndex <= numberOfTables; ++tableIndex)
  707.         {
  708.             tableHandle = Get1IndResource('aedt', tableIndex);
  709.             FailResError();
  710.  
  711.             HLock(tableHandle);
  712.  
  713.             Size tableSize = GetHandleSize(tableHandle);
  714.             FailMemError();
  715.  
  716.             short tableElements = (short)(tableSize / sizeof(AEDTResource));
  717.  
  718.             AEDTResource* tablePtr = (AEDTResource*) *tableHandle;
  719.  
  720.             for (short eventIndex = 1; eventIndex <= tableElements; ++eventIndex)
  721.             {
  722.                 // Install a single event handler for all events 
  723.                 OSErr osErr = AEInstallEventHandler(tablePtr->eventClass, tablePtr->eventID, (AEEventHandlerProcPtr) TApplication::AppleEventsDispatch, tablePtr->eventRefCon, false);
  724.                 FailOSErr(osErr);
  725.  
  726.                 ++tablePtr;
  727.             }
  728.  
  729.             HUnlock(tableHandle);
  730.             ReleaseResource(tableHandle);
  731.         }
  732.         fi.Success();
  733.     }
  734.     else    // Recover
  735.     {
  736.         if (tableHandle)
  737.         {
  738.             HUnlock(tableHandle);
  739.             ReleaseResource(tableHandle);
  740.         }
  741.         fi.ReSignal();
  742.     }
  743. }
  744.  
  745. //----------------------------------------------------------------------------------------------------------------
  746. pascal OSErr TApplication::AppleEventsDispatch(AppleEvent* /*message*/,AppleEvent* /*reply*/, long refCon)
  747. {
  748.     OSErr osErr = 0;
  749.     
  750.     switch (refCon) {
  751.     
  752.         case kAEOpenApplication:
  753.         case kAEOpenDocuments:
  754.         case kAEPrintDocuments:
  755.             break;
  756.         case kAEQuitApplication:
  757.             gApplication->DoGatewayEvent(1,kMailEPPCShutDown,0);
  758.             gDone = true;
  759.             break;
  760.         case 'cnct':        // connect
  761.             gApplication->DoGatewayEvent(1,kMailEPPCSchedule,0);
  762.             break;
  763.         case 'disc':        //    disconnect
  764.             gApplication->DoGatewayEvent(1,'disc',0);
  765.             break;
  766.             
  767.         default:
  768.             ASSERTPRINT(false,("Unrecognized AppleEvent\n"));
  769.             break;
  770.         
  771.     }
  772.     
  773.     return osErr;    
  774. }
  775.